home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-04 / msh20.zip / MSHFILES.ZIP / REFMAN.DOC < prev    next >
Text File  |  1992-03-26  |  44KB  |  849 lines

  1.  
  2.                          Mi-Shell Reference Manual
  3.                                 Jean Michel
  4.                        Version 1.10 --- 26 March 1992
  5.  
  6.  
  7. Introduction:
  8.  
  9.     MSH is a ``shell'' which provides a convenient and configurable way to
  10. browse through directories and execute commands on files and sets of files
  11. by a ``point and shoot'' interface.   In contrast to many popular  shells,
  12. MSH is designed to be particularly useful  to a ``power  user;''  there is
  13. no limit to the number of  shortcuts in  everyday work  she can  implement
  14. with it:   an arbitrary sequence of actions (which is written as an  ``MSH
  15. script'')  may  be  assigned  to  each keyboard  key,  and may  depend on  the
  16. environment (like the file currently pointed to, or its extension, etc...).
  17. Of course, MSH is also useful to the average user.
  18.  
  19.  
  20. Installation:
  21.  
  22.     Installation  of  MSH  is  simple.    You  only have  to copy  MSH.EXE  to
  23. some directory in your PATH (the directories which are scanned by  MS-DOS1
  24. to  look  for  commands),  and  copy the  script files  (with extension  .MSH)
  25. to  the  same  directory.    You  should then  modify the  file CONFIG.MSH  to
  26. indicate your display type,  the drives you  can access,  whether you  own
  27. The Berkeley Utilities or not, which directory to use for swap files, which
  28. editor and browser you want to use, etc... In the file there is a series of
  29. lines of the form:
  30.  
  31.     | in the line below, replace "c_blue.msh" by the name
  32.     | of one of the available files describing attributes:
  33.     |  c_mda.msh                  for monochrome displays
  34.     |  c_pcga.msh                 for plasma cga displays
  35.     |  c_blue.msh, c_blue1.msh,
  36.     |  c_blue2.msh, c_white.msh   various possibilities
  37.     |                             for color displays
  38.     |
  39.     "c_blue.msh"loaddefs               | load blue color
  40.                                        | set attributes
  41.  
  42. you  should  do  at  it  says,  e.g.   replace  c_blue by  c_mda  if you  have
  43. a monochrome display.   You can define your  own colors for  MSH; see  the
  44. appendix on attributes.
  45.     You now modify the following two lines to define your available drives:
  46.  
  47.     "CD" fixed_drives!     | define your fixed drives
  48.     "AB"floppy_drives!     | define your floppy drives
  49.  
  50.     Similarly, there are these 3 lines in the file:
  51.  
  52.     true delta!
  53.     true berk!
  54.     true berk_cpmvrm!
  55. ----------------------------
  56.   1  MS-DOS is a trademark of Microsoft Corporation
  57.  
  58. If  you  do  not  own  DELTA,  you  should  replace  true  by  false  on  the
  59. first  line  and  similarly  for  the  second  and third  if  you do  not  own
  60. The Berkeley Utilities.   The third line refers to whether you want to use
  61. cp, mv and rm or DOS's copy and delete commands for these functions.
  62.     Finally, there are lines reading:
  63.  
  64.     | next line defines the place for "magic" swap files
  65.     (prog_dir)tmp_dir!
  66.     | put swap files in same directory as MSH.EXE
  67.  
  68. They specify the directory to use for swap files (see ``Technical highlight
  69. no.   2'';  used when MSH cannot swap itself  to extended memory).    This
  70. should be a virtual disk or a fast hard disk if you have one.  You can set
  71. tmp_dir to the empty string ("") to disable swapping to disk.
  72.     Also, MSH does not provide a built-in editor:   the idea is rather  to
  73. let you use your own.   If  you do  not have  one,  we include MWE.EXE,  a
  74. multi-window editor which was developed as a demo of the power of TextLib,
  75. a  keyboard  and  screen  management  C  Library  distributed  by  OPENetwork.
  76. Similarly, you may use your own browser  instead of  the built-in one  (it
  77. will be slower).   Of course, you must specify what it is  to MSH; so,  in
  78. CONFIG.MSH you must adapt the lines which say:
  79.  
  80.     "mwe "editor!
  81.     "more "browser!
  82.  
  83. to  specify  what  is  your  editor  and browser;  for  instance,  if you  use
  84. the  mediocre  but  widespread  Wordstar  as  an  editor,  and  the  excellent
  85. public-domain browser list by V.Buerg, you may change the above lines to:
  86.  
  87.     "ws "editor!
  88.     "list "browser!
  89.  
  90. Some people have such a good editor, or like their  bad one so much,  that
  91. they will use it as their browser.   If  your editor  or browser does  not
  92. work with the simple syntax ``edit filename'' or needs extra arguments  or
  93. parameters after the filename, you can still manage, but you will have  to
  94. make more complex modifications to CONFIG.MSH.
  95.  
  96. Starting to use the default configuration
  97.     You can then start MSH just by typing its name.   The initial  display
  98. you get should be:  a menu bar at the top above two panels, each containing
  99. a display of the files in your current directory, and a list  of available
  100. drives.    All  this  is  completely  configurable.    We  describe  here  the
  101. behavior of MSH when you don't modify the CONFIG.MSH file.
  102.     We support extended video modes and extended versions of ANSI.SYS. The
  103. initial number of lines of a panel will be half the number of  total lines
  104. of your display(e.g. in 43-lines EGA mode, you will get 21 lines, and 25 in
  105. the 50-lines VGA mode instead of the usual 12 in  a 25-lines mode; if  you
  106. have a 132-columns mode you will get 3 panels, and 1 panel in a 40-columns
  107. mode).  If you have a VGA or EGA card, you can ask MSH to first switch the
  108. screen to given number n of lines by giving the option -ln on  the command
  109. line (the letter ell); for instance msh -l50 asks MSH to switch the screen
  110. to 50-line mode before starting.  The only values of n currently understood
  111. are 25, 43 and 50.
  112.  
  113.     The  first  line  of  a  panel contains  a  ``pattern'', i.e.  a  wildcard
  114. describing  all  files  in  the  current  directory  at  the  left   (e.g.
  115. c:\dos\*.*).   This is highlighted if the panel is the active  panel.   At
  116. the bottom of a panel are titles  for the various  columns of the  display
  117. (Name.ext, size, time) which are highlighted according to the current sort
  118. order of the panel.
  119.     Most of your interaction with MSH is via what you type on the  command
  120. line.   MSH monitors all your keystrokes and decides what to do with  them
  121. according  to  your  own  instructions  given  via  the CONFIG.MSH  file  (the
  122. default configuration sets things so that  you can  also execute  Mi-Shell
  123. script instructions directly from the command line with the key AltX).
  124.     MSH  when  started  always  tries to  locate  the file  CONFIG.MSH in  the
  125. directory where MSH.EXE is located, unless you give it an explicit filename
  126. as argument.  Two tutorials are on-line when you hit the F1 key to help you
  127. get started.
  128.  
  129. The Mi-Shell script language:
  130.  
  131.     The configuration of MSH is done by  its reading upon  start the  file
  132. CONFIG.MSH. This file is entirely in the  MSH script language.   Any  text
  133. following  a  non-quoted  |  up  to the  end of  a line  is a  comment and  is
  134. ignored.   The rest of the text represents instructions in the MSH  script
  135. language, which is a small Forth-like stack language.
  136.     As  we  proceed  to  describe  the  language,  you  can find  some  useful
  137. examples  which  might  help  in  the  section  ``quick  start  at  modifying
  138. CONFIG.MSH''.
  139.     The  only  elements  of  the  language  are  "  which  delimits  character
  140. strings, brackets () which delimit blocks of  code, and identifiers  which
  141. are  either  words  formed  from  the characters  a--z A--Z  0--9  or dot  (.)
  142. or  underscore  (_)  or  dollar  ($),  or  symbols  constituted by  any  other
  143. single character.   Identifiers represent primitive or user-defined actions
  144. (their  value  is  then  a  block  of code),  or  variables holding  character
  145. strings, excepted that identifiers starting with a digit are interpreted as
  146. character strings as if they were quoted.   This is to allow you to  write
  147. numbers without having to surround them with " (negative numbers like "-1"
  148. still have to be quoted).   A  number is  just a  particular string  whose
  149. content is interpretable as a number, and all string operation apply to it;
  150. only the arithmetic operations try to interpret their string arguments  as
  151. numbers.  Below are some strings:
  152.  
  153.     "abc", "you can put '\"' in a string", 3, "3".
  154.  
  155. The last 2 strings are the same.  Below are some identifiers
  156.  
  157.     foo, bar, foo_bar, +, !, f31.
  158.  
  159.     The  language  is  a  stack  language  like  FORTH.  The  stack  contains
  160. either character strings or pieces (blocks) of  code.   In the  subsequent
  161. descriptions  [top]  represents  the  stack  top,  [top+1] the  next  element,
  162. etc...; push something is the action of pushing something onto the  stack.
  163. Actions typically read one or more values by popping  them from the  stack
  164. (reading [top] always unstacks it) and return possible results by  pushing
  165. them on the stack.   Some actions are predicate-like:   the logical  value
  166. false is represented by the empty  string and  true by  any other  string.
  167. The variables false and true are primitives and contain the values ""  and
  168. "true" respectively.  Variables which hold the value true or false will be
  169. called boolean in what follows.
  170.     A  character  string  is  written  "string"  where  internal `"'  must  be
  171. quoted by preceding them with \; a character string may span several lines
  172. and contain embedded carriage returns.   Merely writing a character string
  173. pushes  it  onto  the  stack.    Other identifiers  cause their  corresponding
  174. actions to be executed or their value to be pushed when encountered, except
  175. that a sequence of actions (or character string denotations) between  `()'
  176. is pushed onto the stack as a piece of code instead.
  177.     A character string or a piece of code may be assigned to an identifier
  178. by the action !; e.g., "hello" "H"!  or ("")"false"!.  In BASIC, this would
  179. be written as H = "hello" or as
  180. false  =  "".    As  a  special  syntactic  convention,  the form  name!    is
  181. equivalent to "name"!, so the above examples may be written "hello"H!  and
  182. ("")false!.
  183.  
  184.     We should mention that some variables are ``system variables'':   like
  185. primitives, they are defined by the system.  Some of them can be set by the
  186. system as well as the user, and when the user sets them some sytem-defined
  187. action results.  An example is cwd, the current working directory:  setting
  188. its value will change the current directory.
  189.     Also,  as  a  special  facility,  a  variable name  beginning  with a  `$'
  190. represents a MS-DOS system variable (such  as PATH or  COMSPEC); the  name
  191. must  be  in  uppercase  letters  to  be  recognized  as  a  system  variable.
  192. Assigning  to  such  variables  will  modify  the  MS-DOS  environment.    For
  193. instance:
  194.  
  195.     $PATH ";\mydir"& $PATH!
  196.  
  197. can  be  used  to  modify  the PATH.  Beware!    Only the  local  copy of  the
  198. environment owned by MSH will be modified (which means that you will  lose
  199. your modifications to the environment when leaving MSH; we might provide a
  200. way around that in future versions).
  201.     Some  identifiers  represent  the  name  of  keys,  and  they  are  called
  202. whenever the corresponding key is pressed.   The definable keys and  their
  203. names are:
  204.     Function keys F1--F10 ShiftF1--ShiftF10
  205.                   CtrlF1--CtrlF10 AltF1--AltF10
  206.     Control keys  CtrlA--CtrlZ
  207.                   Ctrl Break is always a ``break'' key, used to  interrupt
  208.                   actions (like get out of loops)
  209.     ``Alt'' keys  AltA--AltZ Alt0--Alt9 AltMinus AltEqual
  210.     Other keys    Home End Left Right PgDn PgUp Down Up
  211.                   Delete Insert BackSpace
  212.                   CtrlHome CtrlEnd CtrlLeft CtrlRight
  213.                   CtrlPgDn CtrlPgUp
  214.                   ShiftDown  ShiftUp  ShiftLeft  ShiftRight  Esc  Tab  BackTab
  215.                   Enter CtrlEnter
  216.                   GreyPlus GreyMinus GreyStar CtrlPrint
  217.     We now proceed to list the primitive actions, arranged by category.
  218.  
  219. ``Language'' functions:
  220.  
  221.     drop      Do nothing with [top] (and so just unstack it).
  222.     dup       Duplicate [top].
  223.     pick      [top] should be some number n.   If these are the objects on
  224.               the stack, starting from the bottom:
  225.               O(n), O(n-1) ...  O(2) O(1) n
  226.               then after the command the stack will look like:
  227.               O(n) O(n-1) ...  O(2) O(1) O(n)
  228.               so that 1 pick is equivalent to dup.
  229.     swap      Exchange [top] and [top+1].
  230.     roll      [top] should be some number n.   If objects on top of  stack
  231.               are:
  232.               O(n), O(n-1) ...  O(2) O(1) n
  233.               after the command they will be:
  234.               O(n-1) ...  O(2) O(1) O(n)
  235.               so that 2 roll is equivalent to swap.
  236.  
  237.     stacksize push as a number the size of the stack.
  238.     not       Push false if [top] is not false, true otherwise.
  239.     =         If [top]=[top+1], push [top] else push false.
  240.     &         push the catenation of [top] and [top+1].
  241.     match     If [top] matches [top+1], push [top] else push false.
  242.     cutfirst  Cuts [top+1] at [top], that is look  for first occurence  of
  243.               string [top] in [top+1], and replace [top] and [top+1] by the
  244.               part of [top+1] after [top] and the  part of [top+1]  before
  245.               [top]  (the  first  may  be  empty if  [top] does  not occur  in
  246.               [top+1]).
  247.     cutlast   Like  cutfirst,  but  looks  for  last  occurence  of  [top]  in
  248.               [top+1].
  249.  
  250.     length    push the length of the string [top].
  251.     substring extract  from  [top+2]  the  substring  which  starts  with  the
  252.               [top+1]th character and ends with the [top]th character, and
  253.               push it on the stack.
  254.     if        If [top+1] is not false execute [top] else do nothing.
  255.  
  256.     ifnot     If [top+1] is false execute [top] else do nothing.
  257.     ifelse    If [top+2] is false execute [top] else execute [top+1].
  258.  
  259.     while     While  execution  of  [top+1]  does  not  yield  false,  execute
  260.               [top].
  261.     #         Interpret the string [top] as a piece of code and execute it.
  262.     @         Interpret [top] as an identifier name and replace it by  its
  263.               value.  If the value is a piece of code, it is ``uncompiled''
  264.               as a character string.
  265.  
  266.     isdefined Interpret [top] as an identifier name.   Push  true if  this
  267.               identifier has been assigned a value, false otherwise.
  268.     !         Interpret [top] as an identifier name and assign [top+1]  to
  269.               it.
  270.  
  271.     +         Push [top+1]+[top](interpreted as numbers).
  272.     -         Push [top+1]-[top](interpreted as numbers).
  273.     *         Push [top+1]*[top](interpreted as numbers).
  274.  
  275.     /         Push [top+1]/[top](interpreted as numbers).
  276.     <         Push  true  if  [top+1]<[top](interpreted  as  numbers),  false
  277.               otherwise.
  278.     le        Push  true  if  [top+1]<=[top](interpreted  as  numbers),  false
  279.               otherwise.
  280.  
  281.     >         Push "true" if [top+1]>[top](interpreted as numbers),  false
  282.               otherwise.
  283.     ge        Push "true" if [top+1]>=[top](interpreted as numbers), false
  284.               otherwise.
  285.  
  286.     debug     System  variable.    If  "true",  MSH  is  in  ``debug''  mode:
  287.               before any identifier is executed, a window pops up  showing
  288.               it and the current state of the stack.
  289.  
  290. Panels, menus, windows and mouse support:
  291.  
  292.     MSH lets you manipulate several kinds of windows:
  293.   - Panels,  wich  are  ``directory  browsers''.    You  get  two of  them  in
  294.     the  default  configuration.    You  can move  them  around, change  their
  295.     attributes,  what  they  display,  keys  associated to  them,  etc...These
  296.     are ``permanent'' windows (they don't disappear when you have finished
  297.     interacting with them).   Permanent windows have numbers (``handles'')
  298.     associated  with  them  on  creation.    You  may  use  these  numbers  to
  299.     reactivate them (put them in front, ready to receive your  keystrokes)
  300.     later  (windows  can  also  be  activated  by clicking  on them  with  the
  301.     mouse).
  302.   - Menus,  which are actually general ``hypertext'' windows where  fields
  303.     in the window have actions associated  to them.   They  can be  either
  304.     permanent  (they  have  then  numbers  associated  to them)  or  temporary
  305.     (they disappear when you make a choice).
  306.   - Message, choice and dialog windows.  The error windows that the system
  307.     displays sometimes are of a similar kind.  These are temporary windows.
  308.     A message just displays some text.  A dialog window displays some text
  309.     and waits for your input.  A choice window allows you to give a Yes/No
  310.     answer.   A menu could do the  same job  but this  provides a  simpler
  311.     solution.
  312.     At  present,  mouse  support  is  limited to  actions done  on clicks  and
  313. double  clicks.     More  complex  interaction  (like  drags)  are  not  yet
  314. implemented,  mostly  because  of  the  complexity of  the necessary  language
  315. support to describe them.
  316.  
  317.  
  318. Panels functions:
  319.  
  320.     panel.install    Creates  a  new  panel.     Only  one  panel  displaying
  321.                      nothing (with number 1) exists at the  start.   Other
  322.                      panels  must  be  created  with  this  command.     One
  323.                      argument must be given on [top], the initial selection
  324.                      pattern  of  the  newly  created  panel.    The  current
  325.                      panel is set to the created panel.   Other attributes
  326.                      of a panel are set/modified with the following system
  327.                      variables.     panel.install  pushes  one  result,  the
  328.                      number assigned to the panel.
  329.     panel.pattern    System  variable.    Represents  the  `pattern'  of  the
  330.                      current panel (the selection pattern displayed at the
  331.                      top  of  the  panel).    Setting  this  variable  causes
  332.                      the  panel  to  be  refreshed  by reading  from disk  the
  333.                      list  of  files  matching  the  pattern (the  father  and
  334.                      subdirectories  of  the  current  directory  are  always
  335.                      displayed).     As  a  special  facility,  this  can  be
  336.                      assigned  a  pathname  composed  of  the  pathname  of  a
  337.                      ``.zip''  file  +  a  pattern.    The  panel  will  then
  338.                      display the list of all files inside  that zip  which
  339.                      correspond to the given pattern.  We might add support
  340.                      for other kinds of archives (.lzh, .arj, .arc,  .zoo)
  341.                      in the future.
  342.     panel.type       Returns  the  type  of  the  current  panel:    ""  for
  343.                      ordinary panels, ".zip" for a zip archive.
  344.  
  345.     panel.sort       System  variable.    Represents  the  sort  order of  the
  346.                      current  panel.    It  can  be  assigned  the  following
  347.                      values:
  348.                  "N" --- sort the panel by name;
  349.                  "S" --- sort the panel by size;
  350.                  "T" --- sort the panel by date;
  351.                  "E" --- sort the panel by extension.  Sorting by extension
  352.                      keeps as a secondary key the previous sort,  whatever
  353.                      it was.   This is reflected in the highlighted titles
  354.                      at the bottom of the panel.It also means that in  the
  355.                      case of an extension sort, the value of panel.sort is
  356.                      actually one of "EN", "ES" or "ET".
  357.     panel.size       Boolean  system  variable  which  controls  whether  the
  358.                      file size is displayed for each file  of the  current
  359.                      panel.
  360.     panel.attrs      Like panel.size, controls whether the read/write/system--
  361.                      /hidden attributes are displayed.
  362.     panel.date       Like  panel.size,  controls  whether  the  last  modified
  363.                      date is displayed.
  364.     panel.time       Like  panel.size,  controls  whether  the  last  modified
  365.                      time is displayed.
  366.     panel.sec        Like  panel.size,  controls  whether  the  last  modified
  367.                      time is displayed up to the second.
  368.  
  369.     panel.on         Boolean system variable.  Controls whether the current
  370.                      panel is on.   When off, the panel won't be displayed;
  371.                      this is useful to have temporarily an unimpeded  view
  372.                      of  the  screen  behind  the  panel (in  addition to  the
  373.                      panels, the menu bar can be shut off by  uninstalling
  374.                      it;  this  allows  the  use  of  MSH  as  a  ``silent''
  375.                      background task).
  376.     panel.rc         System  variable  representing  the  number  of rows  and
  377.                      columns  of  the  current  panel.    When  read causes  2
  378.                      values to be pushed on the stack, first the number of
  379.                      lines and then the number of columns.   Similarly  it
  380.                      should be set by pushing 2 values on the stack  (e.g.
  381.                      12 40 panel.rc!).
  382.  
  383.     panel.startrc    System variable.   Represents the start row and start
  384.                      column of the current panel (the  coordinates of  the
  385.                      top left corner).
  386.     panel.nbfiles    push the total number of entries of the current panel.
  387.  
  388.     panel.att        Function  taking  4  arguments  representing  the  video
  389.                      attributes used to display the pattern.   They should
  390.                      be given in ANSI format and represent:
  391.                      Normal --- the normal attribute for files in a panel;
  392.                      Current --- the attribute of current  name,  the file
  393.                      pointed to by the cursor;
  394.                      Selected --- the attribute of selected files;
  395.                      Selected + Current --- the attribute of current  name
  396.                      when it happens to be a selected file.
  397.  
  398.     current.name     push the filename of the entry pointed by the  cursor
  399.                      in  the  current  panel  (this  entry  will  be  called
  400.                      `current name' in the subsequent descriptions).
  401.  
  402.     current.isdir    push  false  if  current  name  is  not  a  directory,
  403.                      otherwise push current name (usable as a predicate).
  404.  
  405.     current.size     push the size (in bytes) of current name.
  406.  
  407.     current.time     push the last modified time of  current name.    This
  408.                      time is encoded as an integer by the formula:
  409.  
  410.                                        2x(seconds+
  411.                                       32x(minutes+
  412.                                       64x(hours+
  413.                                       32x(days+
  414.                                       32x(months+
  415.                                       16x(years-1980))))))
  416.  
  417.  
  418.  
  419.  
  420.     current.selected System variable whose value is true or false.  Setting
  421.                      it  to  true  selects  current  name;  this  highlights
  422.                      it  and  marks  it  as  ``selected''  which  means  that
  423.                      current.selected  will  return  true  until  it is  again
  424.                      deselected by setting current.selected to false.
  425.  
  426.     current.pos      System variable which represents the position of  the
  427.                      cursor  in  the  current  panel  relative  to  the  total
  428.                      number  of  files.    Setting  this  variable  moves  the
  429.                      cursor.   Values outside of the interval [0,panel.nb-
  430.                      files-1] are mapped to 0 or panel.nbfiles-1.
  431.  
  432.  
  433. Mouse actions:
  434.  
  435.     User-defined mouse actions on a panel are provided as follows:  when a
  436. mouse event on the panel is detected:
  437.   - It  is  activated  if  it  was not  active  (and panel.on_activate  (which
  438.     should contain an action) is executed).
  439.   - A two-part name is built and is executed (it should contain an action);
  440.   - The first part of the name describes the event:
  441.     LeftClick,  LeftDbleClick,  RightClick,  RightDbleClick,  MiddleClick,
  442.     MiddleDbleClick.
  443.   - The end part of the name  describes the area  of the  panel where  the
  444.     event occured:
  445.     N --- On the word ``name'' at the bottom of the panel.
  446.     E --- On the word ``ext''.
  447.     S --- On the word ``size''.
  448.     T --- On the word ``time''.
  449.     UA --- On the up arrow of the scroll bar.
  450.     DA --- On the down arrow of the scroll bar.
  451.     Entry --- On an entry.   In that  case before executing  the name  the
  452.     number of the entry is pushed.
  453.  
  454. Menu functions:
  455.  
  456.     The only function proper to menus  is menu.install.   The  way a  menu
  457. works is by executing actions (pieces of code) associated to fields in its
  458. window (``menu selections'').  When a menu is active, the cursor keys move
  459. between menu selections.   The currently highlighted selection is executed
  460. when pressing the key Enter or when  clicking with the  mouse on  it.   An
  461. Escape or clicking outside a selection  field quits the  menu without  any
  462. selection being done.   The arguments to menu.install describe  completely
  463. the menu.  They are in order:
  464.   - A list of actions (pieces of  code) to  be executed  for various  menu
  465.     selections.
  466.   - A string, the text of the menu window.  Fields which should operate as
  467.     menu selections are delimited by % in that string (a  % can be put  in
  468.     the menu by doubling it:   %%).   The fields are matched to actions in
  469.     order.  There should be exactly as many actions as there are fields.
  470.   - An  action  which  is  executed  when  the  menu  is  exited  without  any
  471.     selection made (often the empty action  () is  suitable).   This  will
  472.     occur when the user has activated a menu and then hits ESC.
  473.   - The  coordinates  of  where  to  put the  upper left  corner  of the  menu
  474.     window (a "-1" means center the menu in that direction).
  475.   - Three video attributes given as ANSI strings, to use for displaying the
  476.     menu:
  477.     Normal --- the attribute for normal text in the menu window;
  478.     Selection --- the attribute of a menu selection;
  479.     Highlighted --- the attribute of the highlighted menu selection;
  480.   - A  boolean  value  wich  determines  if  the  menu  window should  have  a
  481.     border.
  482.   - A boolean value wich determines if the menu should be permanent.
  483.     For a permanent menu, menu.install returns a value, the number assigned
  484. to the menu.
  485.  
  486.  
  487. Permanent Windows Control:
  488.  
  489.     Two functions control permanent windows:
  490.     window.activate  Takes as argument the number of the window to activate
  491.                      (panel  or  menu).    An  active  menu  is recognized  by
  492.                      having a higlighted selection.   An active panel  has
  493.                      a highlighted title (and if any files are  displayed,
  494.                      current  name  is  highlighted).     When  activating  a
  495.                      panel, the action panel.onactivate is executed.   This
  496.                      can be set by the user; in the default  configuration
  497.                      what it does is attach to the directory of the panel.
  498.                      An active window is put on top of the others.
  499.  
  500.     window.uninstall Takes as argument the number of the window to delete;
  501.                      deletes that window (menu or panel).
  502.  
  503.     It is sometimes convenient to give consecutive numbers to a series  of
  504. panels or menus (the functions next_panel and previous_panel of the default
  505. configuration do that).   The number given  to a newly  created window  is
  506. the first available number, so this can be arranged  by just creating  the
  507. windows consecutively when there has been no deletions.
  508.  
  509. Other Windows:
  510.  
  511.     message  Display [top] as a message with title [top+1].   This message
  512.              is left displayed until any key is typed.  If the text of the
  513.              message does not fit on the screen, it is shown screenful  by
  514.              screenful until the end.  This can provide a primitive kind of
  515.              browser.
  516.  
  517.     flash    Display [top] as a message with title [top+1].   This message
  518.              is left displayed for the number of milliseconds specified by
  519.              [top+2].
  520.  
  521.     ok       Display [top] as a message and ask confirmation with a Yes No
  522.              choice.   Replaces [top] by false in case of non confirmation
  523.              (so may be used as a predicate).
  524.  
  525.     input    Display [top+1] as a message and ask for input in a  field of
  526.              length [top].  The input is pushed on the stack.
  527.  
  528.     getkey   Display [top] as a message with title [top+1].   Return as  a
  529.              character string the name of the first key typed.
  530.  
  531.     alertatt System variable which can only be set.   Its value represents
  532.              (in ANSI format) the color attribute to be used for the above
  533.              windows.  (``alert'' is the name for the temporary ``pop-up''
  534.              windows of MSH: the ones mentioned above, the warnings and the
  535.              debug window).
  536.  
  537.  
  538.  
  539. Command line:
  540.  
  541.     cmd.del       Delete the current character in the command line.
  542.  
  543.     cmd.end       Go to the end of the command line.
  544.  
  545.     cmd.home      Go to the beginning of the command line.
  546.  
  547.     cmd.left      Go one character left in the command line.
  548.  
  549.     cmd.right     Go one character right in the command line.
  550.  
  551.     cmd.wordleft  Go one word left in the command line.
  552.     cmd.wordright Go one word right in the command line.
  553.  
  554.     cmd.clear     Reset to zero the command line.
  555.  
  556.     cmd           System variable representing the command line.   Reading
  557.                   it pushes the command line contents.   Setting it writes
  558.                   [top]  to  the  command  line;  but note  that  the text  is
  559.                   added  to  the  command  line  where the  cursor  is in  it.
  560.                   Call cmd.clear first to replace the command line contents
  561.                   by new contents.
  562.  
  563.     cmd.imode     Boolean system variable representing if the command line
  564.                   is in insert mode.
  565.  
  566. Other:
  567.  
  568.     read         Read the file whose name is [top] and push as a string its
  569.                  contents.
  570.     write        Writes  (creates  or  appends)  to  the  file whose  name  is
  571.                  [top+1] the string [top].
  572.     unlink       removes file whose name is [top].
  573.     capturescreenGrabs the contents of the screen as a string and push  it
  574.                  on the stack.
  575.     progpathname push the pathname of msh.exe.
  576.     cwd          System variable holding the name of the current directory.
  577.                  Setting it attaches to the directory whose name is [top].
  578.     linescols    System  variable  holding  the  total  number  of  lines  and
  579.                  columns  on  the  screen.    It  may be  used in  conjunction
  580.                  with panel.rc and panel.startrc to program a setup for the
  581.                  screen.
  582.  
  583.     execute      Send [top] to command.com to be executed.
  584.     magic        System variable.  If not false, should specify a directory
  585.                  where MSH will swap itself out  of memory before  sending
  586.                  any  command  to  MS-DOS  for  execution  if it  cannot  swap
  587.                  itself to extended memory.  As a special convention, if it
  588.                  starts with a `*', it means that swapping  to XMS is  not
  589.                  desired.  See ``Technical highlight no.  2''.
  590.     page         Call the built-in browser.   It takes 9  arguments:   the
  591.                  name  of  the  file  to  browse followed  by the  coordinates
  592.                  of the window for the browser (start  row, start  column,
  593.                  number of rows, number of colums) and by the list of video
  594.                  attributes to use in the browser:
  595.                  Browser  window  ---  the  attribute  of  the window  of  the
  596.                  browser.
  597.                  Browser highlight --- the attribute of the status line and
  598.                  of highlighted text in the browser.
  599.                  Empty --- the attribute used when showing empty space  in
  600.                  the browser.
  601.                  Tab  ---  the  attribute  used  when  showing  tabs  in  the
  602.                  browser.
  603.  
  604.     beep         As its name says.
  605.     time         push   the   current   time   (in   the   same   format   as
  606.                  current.time).
  607.  
  608.     timer        MSH has a ``timer'' which allows you  to do some  actions
  609.                  at regular times (which may be used to  show a clock)  or
  610.                  after  some  delay  (which  may  be used  to  set an  alarm).
  611.                  [top]  should  contain  the  action  to  do  (as a  piece  of
  612.                  code) and [top+1] a number specifying how many ticks (1=17
  613.                  sec.)   from now this action should be  done.   To do  an
  614.                  action repeatedly, you can write an action which contains
  615.                  a call to set the timer with itself, e.g.   after (f 1000
  616.                  (g)timer)g!   a call to g will execute f repeatedly every
  617.                  1000 ticks.
  618.  
  619.     reinitmouse  With  some  versions  of  the  Microsoft  mouse  driver  and
  620.                  some mouse programs, the mouse driver  in MSH may  become
  621.                  inactivated  when  returning  from  execute.    This  command
  622.                  reinitializes it (it is not done systematically since  it
  623.                  takes 1 to 2 seconds).
  624.     mouse.click  System variable.  Holds the interval between the 2 clicks
  625.                  of a mouse double click.   By default nn is 3 which means
  626.                  3 ticks (ie 3/17 sec.).   You may want this  to be a  bit
  627.                  slower if you are not a Mac user ...
  628.     quit         Quit MSH.
  629.  
  630.  
  631. A quick start at modifying .MSH files:
  632.     The first thing you might want to  do is add  to EXT.MSH  instructions
  633. to deal with other types of  files,  recognized by their extension.    For
  634. instance,  I  use  Knuth's  TeX  text-processing  language,  which  produces
  635. device-independent  output  files  ready  to  be  printed  or  viewed  on  the
  636. screen;  what  I  want  to  do  when I  point  to such  a file,  say  foo.dvi,
  637. and  order  MSH  to  act  by  pressing  the  Enter  key,  is  to  see  what's
  638. in  it,  i.e.  call  my  previewer  (called  view)  with  a  command  such  as
  639. view  foo.dvi.    What  I  did  in order  to get  this is  add a  line to  the
  640. series of lines in EXT.MSH which end by extension_something (a typical one:
  641. (current.name pager)extension_cfg!)  saying:
  642.  
  643.     ("view "current.name & execute)extension_dvi!
  644.  
  645. how  does  this  work?    When  enter  is pressed,  by  a mechanism  described
  646. below, MSH sees that the command line is empty and decides to  execute the
  647. identifier extension_xxx where xxx is the extension of current  name.   It
  648. is the line above which gives a definition to the identifier extension_dvi.
  649. The final !   is the assignment  operator which  assigns to  extension_dvi
  650. what's  on  the  stack.    What  is  there  is the  code  in brackets  at  the
  651. beginning  of  the  line,  which  has  been  pushed by  the simple  virtue  of
  652. appearing  there.     What  does  this  code  do?     First,  it  pushes  the
  653. string "view " on the stack, then current name,  then catenates [top]  and
  654. [top+1](operator  &);  now  [top]  contains  "view foo.dvi";  finally  execute
  655. sends that string to MS-DOS to be executed; you can watch the  whole thing
  656. in action by doing the following steps:
  657.   - Position cursor on foo.dvi and make sure the command line is empty.
  658.   - Press AltD. If your configuration is the  default one,  this make  MSH
  659.     enter debug mode.
  660.   - Press Enter.   You will then see the debugger window, which includes a
  661.     view of the stack.  Press s to step through the code of extension_dvi.
  662.   - Press g (go) when in debug window to leave debug mode.
  663.  
  664.     Let us now have a more elaborate  text explanation by  looking at  the
  665. code which is executed when pressing  Enter.   The code  is the  following
  666. lines in KEYBIND.MSH:
  667.     (cmd
  668.       (execsave)
  669.       (act_on_cur)
  670.       ifelse
  671.     )Enter!
  672.  
  673. We first put the contents of  the command  line on the  stack (cmd).    To
  674. understand  what  happens  next  you  have to  notice that  the rest  consists
  675. of  2  blocks  of  code  followed  by ifelse.    That's  a perfectly  ordinary
  676. if construct, excepted that control structures don't  always look nice  in
  677. reverse polish notation.  The way ifelse works is:  it expects 2 blocks of
  678. code on the stack, and, above that, a value which is false  (empty string)
  679. or not (non-empty string), and execute one or the other piece of code based
  680. on that value.   The net effect here is to execute the first piece of code
  681. if the command line is non-empty and the second otherwise.
  682.     The first piece is a definition:
  683.  
  684.     (cmd dup cmdlist nl&swap&cmdlist!execute
  685.           cmd.clear refresh)execsave!
  686.  
  687. it recalls again the command line, duplicates it, uses one copy to store in
  688. the circular list of commands cmdlist (where previously typed commands are
  689. kept, separated by newlines (the content of the variable nl), for reuse if
  690. recalled by the user), and executes the other copy; then clears the command
  691. line and calls refresh; this last is itself a definition that you can find
  692. in STDDEFS.MSH:
  693.  
  694.     (cwd panel.pattern filepart makename panel.pattern!)
  695.            refresh!
  696.  
  697. The purpose is to refresh the display  in the current  panel, which  might
  698. be necessary since the executed command  may have  destroyed files  and/or
  699. changed directories.  To do that, we first get the current directory's name
  700. on the stack, then catenate to it the filename part of the wildcard of the
  701. current panel (usually "*.*", but it may be set  to something else),  then
  702. put that as the pattern to select files in the current panel.  filepart and
  703. makename are also definitions that we don't show here.
  704.  
  705.     Let's look now at what we do if the command line is empty:
  706.  
  707.     (current.isdir
  708.      (current.name cwd! refresh)
  709.      ("extension_" current.name extension&#)
  710.      ifelse
  711.     )act_on_cur!
  712.  
  713. We  have  again  an  if  which  tests  if  current  name  is  a  directory  or
  714. not.  current.isdir is a predicate, which as all predicates, by convention
  715. returns one of the strings "" (false)  or "true".   If  current name is  a
  716. directory, we attach to it (current.name cwd!)  and refresh.  Otherwise, we
  717. construct an identifier extension_xxx where xxx is the extension of current
  718. name and execute that (#).  extension is defined as follows:
  719.  
  720.     ("."cutlast swap drop)extension!
  721.  
  722. we cut the name into its part before the  "." and after  it, and drop  the
  723. part before it.
  724.     The  other  thing  I  want  to do  with dvi  files is  turn  them into  HP
  725. LaserJet output, which I do with dvihp.exe, and that second type of action
  726. was associated with the CtrlEnter key.
  727.  
  728. Technical highlight number one:  long command lines and The Berkeley Utili-
  729. ties:
  730.  
  731.  
  732.  
  733.  
  734.  
  735.  
  736.  
  737.  
  738.  
  739.  
  740.  
  741.  
  742.  
  743.  
  744.  
  745.  
  746.  
  747.  
  748.  
  749.  
  750.  
  751.  
  752.  
  753.  
  754.  
  755.  
  756.  
  757.  
  758.  
  759.  
  760.  
  761.  
  762.  
  763.  
  764.     MSH supports (almost) arbitrarily long command lines for programs which
  765. recognize its conventions (like The Berkeley Utilities).  For instance, if
  766. you use the BERK.MSH configuration with cp, mv, rm  enabled, and select  a
  767. lot of files and press F6 (move), you will be asked to confirm a very long
  768. command starting with mv, and if you agree mv will correctly move the whole
  769. list to the next panel.   This is quite  advantageous compared to  looping
  770. on mv of each file,  since mv  is loaded  only once,  so the  job is  done
  771. much faster.  You may wonder how this is possible, since MS-DOS limits any
  772. command line to 127 characters.   We do this by a  simple trick, which  is
  773. understood by all The Berkeley Utilities, and which you may make your  own
  774. programs understand!  When the command line is greater than 127 characters,
  775. we send only the first 127 to dos; but  before that we  put the rest in  a
  776. buffer,  preceded by its length as a  2-byte integer,  and we  add to  the
  777. MS-DOS environment a variable CMD@=xx, where xx is the  adress (as a  long
  778. decimal integer) of the buffer.   The called program has just to check  if
  779. that variable exists, and if it is the case  catenate to its command  line
  780. the rest of the command line gotten from the address that variable  holds.
  781. Here is some sample code which does just that; this should help  you write
  782.  
  783. your own.
  784.  
  785.     #include <stddef.h>
  786.     #include <stdlib.h>
  787.     #include <string.h>
  788.     #include <malloc.h>
  789.     #include <dos.h>
  790.     /* this program prints the command line under MSH,
  791.        adding the extra part at the end of the normal command.
  792.        This version gets the psp by the TURBO C built-in
  793.        variable _psp. You have to get it another way
  794.        if you use another compiler. */
  795.     int main()
  796.     { unsigned cmdlen=*(char far *)((((long)_psp)<<16)+0x80),
  797.                extralen=0;
  798.       char *com;
  799.       int far *extra;
  800.       char *s=getenv("CMD@");
  801.       if(NULL!=s && (extra=(int far *)atol(s)))
  802.         extralen=*extra;
  803.       com=malloc(cmdlen+extralen+1);
  804.       movedata(_psp,0x81,
  805.                FP_SEG((char far *)com),
  806.                FP_OFF((char far *)com),cmdlen);
  807.       if(extralen)
  808.       { extra++;
  809.         movedata(FP_SEG(extra),FP_OFF(extra),
  810.                  FP_SEG((char far *)(com+cmdlen)),
  811.          FP_OFF((char far *)(com+cmdlen)),
  812.                  extralen);
  813.       }
  814.       com[cmdlen+extralen]=0;
  815.       printf("command=<%s>\n",com);
  816.       return 0;
  817.     }
  818.  
  819.  
  820. Technical highlight number two:  large memory for your commands:
  821.     MSH, like a few advanced products,  can let your  commands use  almost
  822. all available memory in the system when executing.   In order to do  that,
  823. MSH  swaps  itself  out  of  memory,  writing most  of its  image  to disk  or
  824. to extended memory (if available) and leaving only a  small (8K) image  in
  825. memory.  If you have no (or not enough) extended memory and cannot swap to
  826. a virtual disk (in low or expanded memory) this swapping takes some time so
  827. you may want to disable it.  It is under control of the variable magic:  if
  828. magic is false (the empty string), its default value, no swapping to  disk
  829. is done.   Otherwise magic must contain the  name of the  directory to  be
  830. used for swapping (you may specify ``.''   for the current directory,  but
  831. we don't recommend it since you will then have problems on a diskette; you
  832. should specify some directory on your hard disk or a virtual disk).  If you
  833. want to run a program which requires the use  of all your extended  memory
  834. (this happens to be the case for Borland's BC++3.0 on my machine which has
  835. only 2megs), you may want to disable swapping to XMS: this is done  by the
  836. special convention of starting the variable magic with a `*'.
  837.  
  838. Command line options:
  839.  
  840.     In addition to the -l option explained above, there is another possible
  841. option on the command line:
  842.  -m Disables mouse.  If for some reason, you have a mouse but want MSH not
  843.     to use it, use this option.
  844.  
  845.  
  846. How to add your own primitives coded in C to msh:
  847.  
  848.     Read the file TOOLKIT.DOC which is in the toolkit.
  849.